﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Automation.Peers;
using System.Windows.Automation;
using System.Windows.Data;

namespace Kokomo.Controls
{
	public class DocumentTab : HeaderedContentControl
	{
		static DocumentTab()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(DocumentTab), new FrameworkPropertyMetadata(typeof(DocumentTab)));
		}

		public DocumentTab()
		{
		}

		protected override void OnHeaderChanged(object oldHeader, object newHeader)
		{
			base.OnHeaderChanged(oldHeader, newHeader);
		}

		public TabbedDocumentBase TabbedViewParent
		{
			get
			{
				return ItemsControl.ItemsControlFromItemContainer(this) as TabbedDocumentBase;
			}
		}

		#region Content
		protected override void OnContentChanged(object oldContent, object newContent)
		{
			base.OnContentChanged(oldContent, newContent);
		}
		protected override void OnContentTemplateChanged(DataTemplate oldContentTemplate, DataTemplate newContentTemplate)
		{
			base.OnContentTemplateChanged(oldContentTemplate, newContentTemplate);
		}
		protected override void OnContentTemplateSelectorChanged(DataTemplateSelector oldContentTemplateSelector, DataTemplateSelector newContentTemplateSelector)
		{
			base.OnContentTemplateSelectorChanged(oldContentTemplateSelector, newContentTemplateSelector);
		}
		protected override void OnContentStringFormatChanged(string oldContentStringFormat, string newContentStringFormat)
		{
			base.OnContentStringFormatChanged(oldContentStringFormat, newContentStringFormat);
		}
		#endregion

		#region Docked

		#endregion
		#region Floating


		public string FloatingCaption
		{
			get { return (string)GetValue(FloatingCaptionProperty); }
			set { SetValue(FloatingCaptionProperty, value); }
		}

		// Using a DependencyProperty as the backing store for FloatingCaption.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty FloatingCaptionProperty =
			DependencyProperty.Register("FloatingCaption", typeof(string), typeof(DocumentTab), new UIPropertyMetadata(null));
		#endregion

		#region Selection



		public bool IsSelectable
		{
			get { return (bool)GetValue(IsSelectableProperty); }
			set { SetValue(IsSelectableProperty, value); }
		}

		// Using a DependencyProperty as the backing store for IsSelectable.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty IsSelectableProperty =
			DependencyProperty.Register("IsSelectable", typeof(bool), typeof(DocumentTab), new UIPropertyMetadata(true, OnIsSelectableChanged, OnCoerceIsSelectable));

		static object OnCoerceIsSelectable(DependencyObject target, object value)
		{
			return value;
			//TabbedDocumentItem item = (TabbedDocumentItem)target;
			//bool isSelectable = (bool)value;
			//isSelectable &= item.IsDocked;

			//return isSelectable;
		}

		static void OnIsSelectableChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			DocumentTab item = (DocumentTab)target;
			item.InvalidateProperty(IsSelectedProperty);
		}

		public bool IsSelected
		{
			get { return (bool)GetValue(IsSelectedProperty); }
			set { SetValue(IsSelectedProperty, value); }
		}

		// Using a DependencyProperty as the backing store for IsSelected.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty IsSelectedProperty = Selector.IsSelectedProperty.AddOwner(typeof(DocumentTab), new FrameworkPropertyMetadata(OnIsSelectedChanged, OnCoerceIsSelected));

		static object OnCoerceIsSelected(DependencyObject target, object value)
		{
			DocumentTab item = (DocumentTab)target;
			bool isSelected = (bool)value;
			isSelected &= item.IsSelectable;

			return isSelected;
		}

		private static void OnIsSelectedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
		{
			DocumentTab item = (DocumentTab)target;

			bool isSelected = (bool)e.NewValue;
			if (isSelected)
			{
				item.OnSelected();
			}
			else
			{
				item.OnUnselected();
			}
		}

		private void OnUnselected()
		{
			this.RaiseEvent(new RoutedEventArgs(Selector.UnselectedEvent, this));
		}

		private void OnSelected()
		{
			this.RaiseEvent(new RoutedEventArgs(Selector.SelectedEvent, this));
		}
		#endregion

		#region Dragging
		private Point? _dragStartPoint;
		private bool _isDragging;

		protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
		{
			base.OnMouseMove(e);

			if (this._dragStartPoint.HasValue && (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed))
			{
				Point dragStartPoint = this._dragStartPoint.Value;
				Point p = e.GetPosition(this);
				double dx = (p.X - dragStartPoint.X);
				double dy = (p.Y - dragStartPoint.Y);
				if ((dx >= 2) || (dy >= 2))
				{
					this._isDragging = true;
				}
			}

			if (this._isDragging)
			{
				ItemsControl itemsControl = ItemsControl.GetItemsOwner(this);
				Panel parentPanel = this.FindAncestor<Panel>();
				if (parentPanel != null)
				{
					//FrameworkElement.hit
				}
			}
		}
		protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e)
		{
			base.OnMouseLeftButtonUp(e);
			this._dragStartPoint = null;
			this._isDragging = false;
			this.ReleaseMouseCapture();
		}
		#endregion

		#region Input events
		protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
		{
			this.Focus();
			e.Handled = true;

			this._dragStartPoint = e.GetPosition(this);
			this.CaptureMouse();

			base.OnMouseLeftButtonDown(e);
		}
		protected override void OnGotFocus(RoutedEventArgs e)
		{
			if (!this.IsSelected)
			{
				this.IsSelected = true;
				//e.Handled = true;
			}
			base.OnGotFocus(e);
		}
		#endregion
	}
}
